/* isr.c - interrupt service routines */

#include	"common.h"
#include	"isr.h"
#include	"monitor.h"

isrp intr_handlers[256];
extern u8int sched_reentry;

void isr_handler(struct registers regs){
	isrp handler;

	if(regs.int_no != 128){
		monitor_write("Interrupt received - ");
		monitor_write_dec(regs.int_no);
		monitor_write("\n");
	}

	if(regs.int_no > 255){
		monitor_write("Fatal error - int_no = ");
		monitor_write_hex(regs.int_no);
		monitor_write(", eax = ");
		monitor_write_hex(regs.eax);
		monitor_write("\n");
		return;
	}

	if(intr_handlers[regs.int_no]){
		handler = intr_handlers[regs.int_no];
		(*handler)(regs);
	}else{
		monitor_write("Isr handler not exists.\n");
		monitor_write("eax = ");
		monitor_write_hex(regs.eax);
		monitor_write(", eip = ");
		monitor_write_hex(regs.eip);
		if(regs.int_no == 13){
			monitor_write(", sched_reentry = ");
			monitor_write_hex(sched_reentry);
			monitor_write("\n");
		}
		monitor_write("\n");
		while(1);
	}
}

void reg_intrh(u8int n, isrp handler){
	if(handler){
		monitor_write("Get handler of vec: ");
		monitor_write_dec(n);
		monitor_write("\n");
	}else{
		monitor_write("Warning - null handler ptr.\n");
		monitor_write("\tAt slot: ");
		monitor_write_dec(n);
		monitor_write("\n");
	}
	intr_handlers[n] = handler;
}

void irq_handler(struct registers regs){
	isrp handler;

/*
	monitor_write("irq handler invoked: ");
	monitor_write_hex(regs.int_no);
	monitor_write("\n");
*/
	if(regs.int_no >= 40)
		outb(0xA0, 0x20);
	
	outb(0x20, 0x20);

	if(intr_handlers[regs.int_no]){
		handler = intr_handlers[regs.int_no];
		(*handler)(regs);
	}else{
		monitor_write("Irq handler not exists @ IRQ ");
		monitor_write_dec(regs.int_no);
		monitor_write("\n");
	}
}
